#pragma once

//#include "Vector2D.h"
//#include "GameObject.h"

	// Forward declaration of game object component (for Component message)
	class GameComponent;
	class GameObject;

	// Message types
	enum MessageType
	{
		MT_KeyDown,
		MT_CharDown,

		MT_Build,
		MT_Component,
		MT_Destroy,
		MT_Erase,

		MT_LoadTexture,

		MT_Collision,
		MT_PlaySound,
		MT_MAX
	};

	// base Message class
	class Message
	{
	public:
		Message(MessageType id): TypeID(id){};
		virtual ~Message(){};

		MessageType GetType() { return TypeID; }

	private:
		MessageType TypeID;
	};
	//////////////////////
	// Message subtypes //
	//////////////////////

	// Message to Factory to build an object
	//class BuildMessage : public Message
	//{
	//public:
	//	BuildMessage(Serializer& serializer)
	//		: Message(MT_Build)
	//	{
	//		serializer.ReadData(ObjType);
	//		serializer.ReadData(Position);
	//		serializer.ReadData(Direction);
	//		serializer.ReadData(Scale);
	//	}

	//	BuildMessage(std::string objType, Vector2D pos = Zero(), float dir = 0.0f, float scale = 1.0f)
	//		: Message(MT_Build),ObjType(objType),Position(pos),Direction(dir),Scale(scale){}

	//	std::string GetObjectType() { return ObjType; }
	//	Vector2D GetPos() { return Position; }
	//	float GetDir() { return Direction; }
	//	float GetScale() { return Scale; }

	//private:
	//	std::string ObjType;
	//	Vector2D Position;
	//	float Direction;
	//	float Scale;
	//};

	//// Message to Factory to destroy an object/to systems to erase an object's components
	//class DestroyMessage : public Message
	//{
	//public:
	//	// Type should either be MT_Destroy or MT_Erase
	//	DestroyMessage(unsigned instID, GameObjectType objType, MessageType mt = MT_Destroy)
	//		: Message(mt),InstID(instID),ObjType(objType){};

	//	unsigned GetInstID() { return InstID; }
	//	GameObjectType GetObjType() { return ObjType; }

	//private:
	//	unsigned InstID;
	//	GameObjectType ObjType;
	//};

	// Message that a key has been pressed (can be regular or character)
	class KeyDownMessage : public Message
	{
	public:
		KeyDownMessage(int key, MessageType type = MT_KeyDown)
			: Message(type),Key(key){};

		int GetKey() { return Key; }

	private:
		int Key;
	};

	//// Message to an object that it has collided with another object.
	//class CollisionMessage : public Message
	//{
	//public:
	//	CollisionMessage(unsigned instID, GameObjectType objType, float weight)
	//		: Message(MT_Collision),InstID(instID), ObjType(objType),Weight(weight){};

	//	unsigned GetInstID() { return InstID; }
	//	GameObjectType GetObjType() { return ObjType; }
	//	float GetWeight() { return Weight; }

	//private:
	//	unsigned InstID;
	//	GameObjectType ObjType; // type of object that the object collided with
	//	float Weight; // used to determine the amount of damage caused
	//};

	//class AudioMessage : public Message
	//{
	//public:
	//	AudioMessage(Serializer& serializer)
	//		: Message(MT_PlaySound)
	//	{
	//		serializer.ReadData(Num);
	//	}

	//	AudioMessage(SoundType num)
	//		: Message(MT_PlaySound),Num(num) {}

	//	SoundType GetNum() { return Num; }

	//private:
	//	SoundType Num;
	//};

	//// Currently only used for loading the background texture, but
	//// I'm hoping I can use something similar to allow smarter loading of
	//// assets (i.e. don't load it if you don't have to).
	//class LoadTextureMessage : public Message
	//{
	//public:
	//	LoadTextureMessage(Serializer& serializer)
	//		: Message(MT_LoadTexture)
	//	{
	//		std::string file;
	//		serializer.ReadData(file);
	//		Filename = "assets/" + file;
	//	}

	//	std::string GetFilename() { return Filename; }

	//private:
	//	std::string Filename;
	//};

	///******************************************************************************* 
	// * I don't particularly like this message, as it passes pointers to game object
	// * components, but I wanted to reduce the number of global pointers and pointers 
	// * to other systems as much as possible. If I figure out some better way to have
	// * components add themselves to systems, I'll eliminate this.
	// *******************************************************************************/
	//// Message to a system to add a component
	//class ComponentMessage : public Message
	//{
	//public:
	//	ComponentMessage(unsigned instID, ComponentType type, ObjectComponent* component)
	//		: Message(MT_Component),InstID(instID), Type(type), Component(component){}

	//	unsigned GetInstID() { return InstID; }
	//	ComponentType GetComponentType() { return Type; }
	//	ObjectComponent* GetComponent() { return Component; }

	//private:
	//	unsigned InstID;
	//	ComponentType Type;
	//	ObjectComponent* Component;
	//};
//}
